1 Setup

renv::snapshot(
  prompt = FALSE
)
## * Lockfile written to '/Volumes/GoogleDrive/My Drive/Analytics/brl_usd/renv.lock'.
rm(list = ls())


wd <- here::here()
wd
## [1] "/Volumes/GoogleDrive/My Drive/Analytics/brl_usd"
library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──
## ✓ ggplot2 3.3.5     ✓ purrr   0.3.4
## ✓ tibble  3.1.6     ✓ dplyr   1.0.7
## ✓ tidyr   1.2.0     ✓ stringr 1.4.0
## ✓ readr   2.1.2     ✓ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
# library(tidymodels)
# library(tidytext)
# set the plotting theme to `theme_minimal`
ggplot2::theme_set(ggplot2::theme_minimal())

# set print options
options(max.print = 100000)   # set the number of lines to print
options(scipen = 999)         # digits longer than this will be converted to scientific notation

2 Get Data on BRL per 1 USD

url <- "https://query1.finance.yahoo.com/v7/finance/download/BRL=X?period1=1070150400&period2=1642809600&interval=1d&events=history&includeAdjustedClose=true"


brl_usd <-
  readr::read_csv(
    file = url,
    col_types = readr::cols(
      Date = col_date(format = ""),
      Open = col_double(),
      High = col_double(),
      Low = col_double(),
      Close = col_double(),
      `Adj Close` = col_double(),
      Volume = col_double()
      ),
    na = c("", "NA", "null")
  ) %>% 
  janitor::clean_names() %>% 
  dplyr::arrange(date)

dplyr::glimpse(brl_usd)
## Rows: 4,735
## Columns: 7
## $ date      <date> 2003-12-01, 2003-12-02, 2003-12-03, 2003-12-04, 2003-12-05,…
## $ open      <dbl> 2.946, 2.923, 2.931, 2.931, 2.943, 2.934, 2.940, 2.933, 2.94…
## $ high      <dbl> 2.946, 2.931, 2.936, 2.943, 2.948, 2.943, 2.940, 2.944, 2.94…
## $ low       <dbl> 2.923, 2.923, 2.926, 2.931, 2.934, 2.934, 2.931, 2.933, 2.93…
## $ close     <dbl> 2.923, 2.931, 2.931, 2.943, 2.934, 2.940, 2.933, 2.942, 2.93…
## $ adj_close <dbl> 2.923, 2.931, 2.931, 2.943, 2.934, 2.940, 2.933, 2.942, 2.93…
## $ volume    <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
rm(url)

3 Viz

3.1 Price Scenarios

reais_per_dollar <- seq(from = 4.5, to = 6.5, by = 0.05)
price_in_reais <- seq(from = 600000, to = 670000, by = 1000)

price_scenarios <-
  purrr::cross_df(
    list(
      reais_per_dollar = reais_per_dollar, 
      price_in_reais = price_in_reais
    )
  ) %>% 
  mutate(
    price_in_dollars = price_in_reais / reais_per_dollar
  )


knitr::kable(
  head(price_scenarios, 100),
  format = "html",
  digits = c(2, 0, 0),
  format.args = list(big.mark = ",")
)
reais_per_dollar price_in_reais price_in_dollars
4.50 600,000 133,333
4.55 600,000 131,868
4.60 600,000 130,435
4.65 600,000 129,032
4.70 600,000 127,660
4.75 600,000 126,316
4.80 600,000 125,000
4.85 600,000 123,711
4.90 600,000 122,449
4.95 600,000 121,212
5.00 600,000 120,000
5.05 600,000 118,812
5.10 600,000 117,647
5.15 600,000 116,505
5.20 600,000 115,385
5.25 600,000 114,286
5.30 600,000 113,208
5.35 600,000 112,150
5.40 600,000 111,111
5.45 600,000 110,092
5.50 600,000 109,091
5.55 600,000 108,108
5.60 600,000 107,143
5.65 600,000 106,195
5.70 600,000 105,263
5.75 600,000 104,348
5.80 600,000 103,448
5.85 600,000 102,564
5.90 600,000 101,695
5.95 600,000 100,840
6.00 600,000 100,000
6.05 600,000 99,174
6.10 600,000 98,361
6.15 600,000 97,561
6.20 600,000 96,774
6.25 600,000 96,000
6.30 600,000 95,238
6.35 600,000 94,488
6.40 600,000 93,750
6.45 600,000 93,023
6.50 600,000 92,308
4.50 601,000 133,556
4.55 601,000 132,088
4.60 601,000 130,652
4.65 601,000 129,247
4.70 601,000 127,872
4.75 601,000 126,526
4.80 601,000 125,208
4.85 601,000 123,918
4.90 601,000 122,653
4.95 601,000 121,414
5.00 601,000 120,200
5.05 601,000 119,010
5.10 601,000 117,843
5.15 601,000 116,699
5.20 601,000 115,577
5.25 601,000 114,476
5.30 601,000 113,396
5.35 601,000 112,336
5.40 601,000 111,296
5.45 601,000 110,275
5.50 601,000 109,273
5.55 601,000 108,288
5.60 601,000 107,321
5.65 601,000 106,372
5.70 601,000 105,439
5.75 601,000 104,522
5.80 601,000 103,621
5.85 601,000 102,735
5.90 601,000 101,864
5.95 601,000 101,008
6.00 601,000 100,167
6.05 601,000 99,339
6.10 601,000 98,525
6.15 601,000 97,724
6.20 601,000 96,935
6.25 601,000 96,160
6.30 601,000 95,397
6.35 601,000 94,646
6.40 601,000 93,906
6.45 601,000 93,178
6.50 601,000 92,462
4.50 602,000 133,778
4.55 602,000 132,308
4.60 602,000 130,870
4.65 602,000 129,462
4.70 602,000 128,085
4.75 602,000 126,737
4.80 602,000 125,417
4.85 602,000 124,124
4.90 602,000 122,857
4.95 602,000 121,616
5.00 602,000 120,400
5.05 602,000 119,208
5.10 602,000 118,039
5.15 602,000 116,893
5.20 602,000 115,769
5.25 602,000 114,667
5.30 602,000 113,585
5.35 602,000 112,523
glimpse(price_scenarios)
## Rows: 2,911
## Columns: 3
## $ reais_per_dollar <dbl> 4.50, 4.55, 4.60, 4.65, 4.70, 4.75, 4.80, 4.85, 4.90,…
## $ price_in_reais   <dbl> 600000, 600000, 600000, 600000, 600000, 600000, 60000…
## $ price_in_dollars <dbl> 133333.3, 131868.1, 130434.8, 129032.3, 127659.6, 126…
plot_line.price_scenarios <-
  price_scenarios %>% 
  dplyr::mutate(
    reais_per_dollar = factor(reais_per_dollar)
  ) %>% 
  ggplot2::ggplot(
    ggplot2::aes(
      x = price_in_reais,
      y = price_in_dollars,
      color = reais_per_dollar
    )
  ) +
  ggplot2::geom_line() +
  ggplot2::scale_x_continuous(
    label = scales::comma
  ) +
  ggplot2::scale_y_continuous(
    label = scales::comma
  ) +
  NULL

plotly::ggplotly(plot_line.price_scenarios)
price_scenarios %>% 
  dplyr::filter(
    price_in_reais == 650000
  ) %>% 
  knitr::kable(
    format = "html",
    digits = c(2, 0, 0),
    format.args = list(big.mark = ",")
  )
reais_per_dollar price_in_reais price_in_dollars
4.50 650,000 144,444
4.55 650,000 142,857
4.60 650,000 141,304
4.65 650,000 139,785
4.70 650,000 138,298
4.75 650,000 136,842
4.80 650,000 135,417
4.85 650,000 134,021
4.90 650,000 132,653
4.95 650,000 131,313
5.00 650,000 130,000
5.05 650,000 128,713
5.10 650,000 127,451
5.15 650,000 126,214
5.20 650,000 125,000
5.25 650,000 123,810
5.30 650,000 122,642
5.35 650,000 121,495
5.40 650,000 120,370
5.45 650,000 119,266
5.50 650,000 118,182
5.55 650,000 117,117
5.60 650,000 116,071
5.65 650,000 115,044
5.70 650,000 114,035
5.75 650,000 113,043
5.80 650,000 112,069
5.85 650,000 111,111
5.90 650,000 110,169
5.95 650,000 109,244
6.00 650,000 108,333
6.05 650,000 107,438
6.10 650,000 106,557
6.15 650,000 105,691
6.20 650,000 104,839
6.25 650,000 104,000
6.30 650,000 103,175
6.35 650,000 102,362
6.40 650,000 101,562
6.45 650,000 100,775
6.50 650,000 100,000
price_scenarios %>% 
  dplyr::filter(
    price_in_reais == 630000
  ) %>% 
  knitr::kable(
    format = "html",
    digits = c(2, 0, 0),
    format.args = list(big.mark = ",")
  )
reais_per_dollar price_in_reais price_in_dollars
4.50 630,000 140,000
4.55 630,000 138,462
4.60 630,000 136,957
4.65 630,000 135,484
4.70 630,000 134,043
4.75 630,000 132,632
4.80 630,000 131,250
4.85 630,000 129,897
4.90 630,000 128,571
4.95 630,000 127,273
5.00 630,000 126,000
5.05 630,000 124,752
5.10 630,000 123,529
5.15 630,000 122,330
5.20 630,000 121,154
5.25 630,000 120,000
5.30 630,000 118,868
5.35 630,000 117,757
5.40 630,000 116,667
5.45 630,000 115,596
5.50 630,000 114,545
5.55 630,000 113,514
5.60 630,000 112,500
5.65 630,000 111,504
5.70 630,000 110,526
5.75 630,000 109,565
5.80 630,000 108,621
5.85 630,000 107,692
5.90 630,000 106,780
5.95 630,000 105,882
6.00 630,000 105,000
6.05 630,000 104,132
6.10 630,000 103,279
6.15 630,000 102,439
6.20 630,000 101,613
6.25 630,000 100,800
6.30 630,000 100,000
6.35 630,000 99,213
6.40 630,000 98,438
6.45 630,000 97,674
6.50 630,000 96,923

3.2 Exchange Over Time

exchange_over_time <-
  brl_usd %>% 
  ggplot2::ggplot(
    ggplot2::aes(
      x = date,
      y = close
    )
  ) +
  ggplot2::geom_line(
    na.rm = TRUE
  ) +
  # ggplot2::geom_vline(
  #   xintercept = lubridate::as_date("2021-01-01")
  # ) +
  NULL

plotly::ggplotly(exchange_over_time)

3.3 Close, Min, Max with 30-Day Windows

# future_exchanges <-
#   brl_usd %>% 
#   dplyr::select(
#     date,
#     close
#   ) %>% 
#   dplyr::mutate(
#     highest_future = cummax(close),
#     lowest_future = cummin(close),
#     highest_future30 = dplyr::lag(x = highest_future, n = 30),
#     lowest_future30 = dplyr::lag(x = lowest_future, n = 30)
#   )
# 
# dplyr::glimpse(future_exchanges)
to_join <-
  brl_usd %>% 
  dplyr::select(
    date,
    close
  ) %>% 
  dplyr::mutate(
    to_delete = "a"
  )

self_joined <-
  to_join %>% 
  dplyr::inner_join(
    y = to_join,
    by = "to_delete",
    suffix = c("", "_future")
  ) %>% 
  dplyr::filter(
    date_future > date - 30 &
      date_future < date + 30
  ) %>% 
  dplyr::select(
    -to_delete
  ) %>% 
  dplyr::arrange(
    date,
    date_future
  )

dplyr::glimpse(self_joined)
## Rows: 201,259
## Columns: 4
## $ date         <date> 2003-12-01, 2003-12-01, 2003-12-01, 2003-12-01, 2003-12-…
## $ close        <dbl> 2.923, 2.923, 2.923, 2.923, 2.923, 2.923, 2.923, 2.923, 2…
## $ date_future  <date> 2003-12-01, 2003-12-02, 2003-12-03, 2003-12-04, 2003-12-…
## $ close_future <dbl> 2.923, 2.931, 2.931, 2.943, 2.934, 2.940, 2.933, 2.942, 2…
max_min_exchange <-
  self_joined %>% 
  dplyr::group_by(
    date
  ) %>% 
  dplyr::summarise(
    close_max = max(close_future),
    close_min = min(close_future)
  ) %>% 
  dplyr::ungroup() %>% 
  dplyr::select(
    -tidyselect::contains("_future")
  ) %>% 
  left_join(
    y = to_join %>% dplyr::select(-to_delete),
    by = "date"
  ) %>% 
  dplyr::mutate(
    diff_close_to_max = close - close_max,
    diff_close_to_min = close - close_min,
    diff_max_to_min = close_max - close_min
  ) %>% 
  dplyr::arrange(
    date
  )

dplyr::glimpse(max_min_exchange)
## Rows: 4,735
## Columns: 7
## $ date              <date> 2003-12-01, 2003-12-02, 2003-12-03, 2003-12-04, 200…
## $ close_max         <dbl> 2.943, 2.943, 2.943, 2.943, 2.943, 2.943, 2.943, 2.9…
## $ close_min         <dbl> 2.860, 2.860, 2.860, 2.860, 2.860, 2.853, 2.853, 2.8…
## $ close             <dbl> 2.923, 2.931, 2.931, 2.943, 2.934, 2.940, 2.933, 2.9…
## $ diff_close_to_max <dbl> -0.020, -0.012, -0.012, 0.000, -0.009, -0.003, -0.01…
## $ diff_close_to_min <dbl> 0.063, 0.071, 0.071, 0.083, 0.074, 0.087, 0.080, 0.0…
## $ diff_max_to_min   <dbl> 0.083, 0.083, 0.083, 0.083, 0.083, 0.090, 0.090, 0.0…
skimr::skim(max_min_exchange)
Data summary
Name max_min_exchange
Number of rows 4735
Number of columns 7
_______________________
Column type frequency:
Date 1
numeric 6
________________________
Group variables None

Variable type: Date

skim_variable n_missing complete_rate min max median n_unique
date 0 1 2003-12-01 2022-01-21 2012-12-26 4735

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
close_max 1113 0.76 3.17 1.27 1.61 2.09 2.96 3.99 5.89 ▇▃▃▁▂
close_min 1113 0.76 2.90 1.13 1.53 1.98 2.79 3.64 5.53 ▇▃▃▁▂
close 447 0.91 2.90 1.17 1.53 1.96 2.38 3.70 5.89 ▇▃▃▁▂
diff_close_to_max 1113 0.76 -0.14 0.13 -1.06 -0.19 -0.10 -0.05 0.00 ▁▁▁▂▇
diff_close_to_min 1113 0.76 0.13 0.12 0.00 0.05 0.09 0.17 1.06 ▇▂▁▁▁
diff_max_to_min 1113 0.76 0.27 0.20 0.04 0.13 0.23 0.35 1.21 ▇▃▁▁▁
# max_min_exchange %>% 
#   dplyr::mutate(
#     year = factor(lubridate::floor_date(x = date, unit = "year"))
#   ) %>% 
#   dplyr::group_by(year) %>% 
#   skimr::skim()
# test <-
#   brl_usd %>% 
#   dplyr::select(
#     date,
#     close
#   ) %>% 
#   dplyr::mutate(
#     close_max = dplyr::lag(x = cummax(close), n = 30)
#   )
# 
# glimpse(test)
p <-
  max_min_exchange %>% 
  tidyr::pivot_longer(
    cols = close_max:close,
    names_to = "type",
    values_to = "value"
  ) %>% 
  ggplot2::ggplot(
    ggplot2::aes(
      x = date,
      y = value,
      color = type
    )
  ) +
  ggplot2::geom_line(
    na.rm = TRUE
  ) +
  ggplot2::scale_color_manual(
    values = c("black", "green", "red")
  ) +
  ggplot2::labs(
    x = "data",
    y = "BRL  por  1  USD"
  ) +
  NULL

# p
plotly::ggplotly(p)

3.4 Diff Min to Max

p <-
  max_min_exchange %>% 
  tidyr::pivot_longer(
    cols = tidyselect::contains("diff_"),
    names_to = "type",
    values_to = "value"
  ) %>% 
  ggplot2::ggplot(
    ggplot2::aes(
      x = date,
      y = value,
      color = type
    )
  ) +
  ggplot2::geom_line(
    na.rm = TRUE
  ) +
  # ggplot2::scale_color_manual(
  #   values = c("black", "green", "red")
  # ) +
  # ggplot2::labs(
  #   x = "data",
  #   y = "BRL  por  1  USD"
  # ) +
  ggplot2::facet_wrap(
    facets = vars(type),
    scales = "free",
    ncol = 1
  ) +
  ggplot2::theme(
    legend.position = "none"
  ) +
  NULL

# p
plotly::ggplotly(p)
p <-
  max_min_exchange %>% 
  ggplot2::ggplot(
    ggplot2::aes(
      x = date,
      y = diff_max_to_min
    )
  ) +
  ggplot2::geom_line(
    na.rm = TRUE
  ) +
  NULL

plotly::ggplotly(p)

4 Add Rolling Calcs

add_rolls <-
  max_min_exchange %>% 
  dplyr::mutate(
    # 1 week
    close_roll_mean_005 = RcppRoll::roll_mean(x = close,
                                              n = 5,
                                              partial = FALSE,
                                              fill = NA,
                                              align = "right",
                                              na.rm = TRUE
                                              ),
    # 2 weeks
    close_roll_mean_010 = RcppRoll::roll_mean(x = close,
                                              n = 10,
                                              partial = FALSE,
                                              fill = NA,
                                              align = "right",
                                              na.rm = TRUE
                                              ),
    # 4 weeks
    close_roll_mean_020 = RcppRoll::roll_mean(x = close,
                                              n = 20,
                                              partial = FALSE,
                                              fill = NA,
                                              align = "right",
                                              na.rm = TRUE
                                              ),
    # 8 weeks
    close_roll_mean_040 = RcppRoll::roll_mean(x = close,
                                              n = 40,
                                              partial = FALSE,
                                              fill = NA,
                                              align = "right",
                                              na.rm = TRUE
                                              ),
    # 16 weeks
    close_roll_mean_080 = RcppRoll::roll_mean(x = close,
                                              n = 80,
                                              partial = FALSE,
                                              fill = NA,
                                              align = "right",
                                              na.rm = TRUE
                                              ),
    # 32 weeks
    close_roll_mean_160 = RcppRoll::roll_mean(x = close,
                                              n = 160,
                                              partial = FALSE,
                                              fill = NA,
                                              align = "right",
                                              na.rm = TRUE
                                              )
  )

dplyr::glimpse(add_rolls)
## Rows: 4,735
## Columns: 13
## $ date                <date> 2003-12-01, 2003-12-02, 2003-12-03, 2003-12-04, 2…
## $ close_max           <dbl> 2.943, 2.943, 2.943, 2.943, 2.943, 2.943, 2.943, 2…
## $ close_min           <dbl> 2.860, 2.860, 2.860, 2.860, 2.860, 2.853, 2.853, 2…
## $ close               <dbl> 2.923, 2.931, 2.931, 2.943, 2.934, 2.940, 2.933, 2…
## $ diff_close_to_max   <dbl> -0.020, -0.012, -0.012, 0.000, -0.009, -0.003, -0.…
## $ diff_close_to_min   <dbl> 0.063, 0.071, 0.071, 0.083, 0.074, 0.087, 0.080, 0…
## $ diff_max_to_min     <dbl> 0.083, 0.083, 0.083, 0.083, 0.083, 0.090, 0.090, 0…
## $ close_roll_mean_005 <dbl> NA, NA, NA, NA, 2.9324, 2.9358, 2.9362, 2.9384, 2.…
## $ close_roll_mean_010 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, 2.9348, 2.9344…
## $ close_roll_mean_020 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
## $ close_roll_mean_040 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
## $ close_roll_mean_080 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
## $ close_roll_mean_160 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…

4.1 Viz

long_df <-
  add_rolls %>% 
  tidyr::pivot_longer(
    cols = -date,
    names_to = "type",
    values_to = "value"
  ) %>% 
  dplyr::filter(
    type == "close" |
      stringr::str_detect(string = type,
                          pattern = "roll_mean"
                          )
  )

dplyr::glimpse(long_df)
## Rows: 33,145
## Columns: 3
## $ date  <date> 2003-12-01, 2003-12-01, 2003-12-01, 2003-12-01, 2003-12-01, 200…
## $ type  <chr> "close", "close_roll_mean_005", "close_roll_mean_010", "close_ro…
## $ value <dbl> 2.923, NA, NA, NA, NA, NA, NA, 2.931, NA, NA, NA, NA, NA, NA, 2.…
p <-
  long_df %>% 
  ggplot2::ggplot(
    ggplot2::aes(
      x = date,
      y = value,
      color = type
    )
  ) +
  ggplot2::geom_line(
    na.rm = TRUE
  ) +
  NULL

plotly::ggplotly(p)